Authorization Code Grant 是相較其他三種授權類型而言,最複雜的一種。但就讓使用者授護的目的而言,這個授權類型相較設計的比較合理也安全。
Client credentials grant 設計上並沒有經過使用者授權,因此它雖然安全,但就目的而言不完全合理。
之前討論身分驗證可以怎麼做的時候曾提過,在做身分驗證前要先註冊實體。同樣地,client 在開始要求授權之前,也得先跟授權伺服器註冊 client 的相關資訊。
註冊資訊 | 說明 |
---|---|
client identifier | client 的唯一識別碼 |
client authentication | client 驗證的方法,如密碼或是 JWT 等 |
client password | client 的密碼驗證方法,若授權伺服器有發密碼的話,則必須提供 HTTP basic authentication scheme |
redirection endpoint | 規範提到 public client 才需要,但實務上還是都會在註冊提供,以確保安全 |
時序圖如下:
@startuml
ResourceOwner <- Client: Redirect to AuthorizationServer
ResourceOwner -> AuthorizationServer: Resource Owner Authenticates
ResourceOwner <- AuthorizationServer: Authorization Code
ResourceOwner -> Client: Authorization Code
Client --> AuthorizationServer: Authenticates and request Access Token
Client <-- AuthorizationServer: Access Token
@enduml
首先會由 client 透過 User Agent 發出授權請求(authorization request)到授權伺服器的授權端口(authorization endpoint),這個請求會帶有下列資訊:
欄位名稱 | 必要參數 | 說明 |
---|---|---|
response_type | REQUIRED | 指的是回應類型為何,以此授權類型的話是 code |
client_id | REQUIRED | client 預先註冊好的唯一識別碼 |
redirect_uri | OPTIONAL | client 預先註冊好的轉導頁面 |
scope | OPTIONAL | 授權範圍 |
state | RECOMMENDED | 亂數,可用來確保授權請求與授權回應為同一使用者 |
而這些參數使用 application/x-www-form-urlencoded
編碼後,把它作為 HTTP query 放到授權端口的後面,並產生 URI。接著讓 Client 使用 302 redirect 到此 URI。
接著這個端口該回應什麼,或是實際上要如何要求使用者授權,協定就沒有特別定義了。協定關心的是接下來的事:如何回傳授權結果給 client。
授權請求的 response_type
是使用 code
,因此成功的話就會把帶有 code
資訊的請求,透過 User Agent 傳送給 redirection endpoint。另外如果授權請求有帶 state
的話,這裡會一併回傳給 client 做確認。
類似地,implicit grant 授權請求的
response_type
是使用token
,回傳給 client 的時候則帶有access_token
資訊
Client 拿到 code
之後,它還不能拿來作為通行證使用,還需要再帶著 code
對授權伺服器提供的 token endpoint 發送 POST 請求。除此之外,還需要額外提供身分驗證資訊--指註冊的所約定好的驗證方法,如最常見的 id / secret 透過 http basic authentication 驗證。
欄位名稱 | 必要參數 | 說明 |
---|---|---|
grant_type | REQUIRED | 協定規定為 authorization_code |
code | REQUIRED | 授權成功回應的 code |
redirect_uri | REQUIRED | 必須與授權請求 redirect_uri 相同 |
最後成功即可拿到 access token 資訊,以及 metadata。
欄位名稱 | 必要參數 | 說明 |
---|---|---|
access_token | REQUIRED | 授權服務發行的 token |
token_type | REQUIRED | 說明 access token 是何種型式 |
expires_in | RECOMMENDED | Token 多久後會過期 |
refresh_token | OPTIONAL | 可用來重換新的 token |
scope | OPTIONAL | 最終接受的授權範圍 |
授權失敗的格式 RFC 裡面已有詳細說明,這裡就不多提
在整個授權流程中,最需要保護的標的就是 token,包括 access token 與 refresh token。
從流程來看,Authorization Code Grant 相較安全的主因是:token 的傳輸都是在後端,對使用者而言是無感或不存在的。也因此攻擊者無法藉由使用者操作不當進而取得 token 與權限。
同時,code
也要盡可能避免被偷。因此一個簡單的方法是,註冊時同時綁定 redirect_uri
的白名單,這樣在授權請求可以進一步阻擋不合法的請求。而使用亂數的 state
並在 redirection endpoint 做確認,也能有效增加安全性。
今天簡單說明了 Authorization Code Grant 的流程。接下來在看 OpenID Connect 時,將會用到今天所介紹的內容。